<?php

/**
 * Clase generla para este ejemplo use como base Adophp y logicamente algunos metodos que he estado usando en los proyectos que he participado
 * En lo personal uso estas variables globales pero como estan pidiendo en un archivo aparte si es posible no hay problema.Lo incluyo para trbajarlo con variables globales
 * @author Alex 
 */
ini_set("memory_limit", "128M");
require 'globales.inc.php';
require 'class.Error.php';

class BD extends ExeError {

    /**
     * Ahora va asi
     *
     */
    private $host = DB_HOST;
    private $user = DB_USER;
    private $pass = DB_PASS;
    public $carpeta = "";
    public $cn;
    private $database = DB_BD;
    public $funcion_ajax;
    public $data_grid;
    public $img_navegacion;
    public $codificacion = "utf-8";
    private static $instancia = null;
    public $menu_navegacion = NULL;


    const ABIERTA = 1;
    const CERRADA = 0;
    public $status = 0;

    function BD() {
        $this->funcion_ajax = "cargar_pagina2";
        $this->data_grid = "";
        $this->img_navegacion = false;
    }

    /**
     * *Abrimos la bd
     */
    public function open() {
        ini_set("memory_limit", "128M");
        $this->cn = mysql_connect($this->host, $this->user, $this->pass) or die(mysql_error());
        mysql_select_db($this->database, $this->cn) or die(mysql_error());
        // Para que la base de datos devuelva las consultas en UTF-8
        mysql_query("SET NAMES UTF8");
        // Hora GMT para todos los registros
        mysql_query("SET time_zone = '+00:00'");
        ini_set("magic_quotes_gpc", 1);
    }

    public static function singleton() {
        if (self::$instancia == null) {
            self::$instancia = new self ( );
        }
        return self::$instancia;
    }

    /**
     * Cierra la bd
     */
    public function close() {
        mysql_close($this->cn);
    }

    /**
     * Ejecutamos una consulta para que nos devuelva resultados
     * @param string $sql Consulta SQL
     */
    public function ExecuteNonQuery($sql) {
        if ($this->status == BD::CERRADA)
            $this->open();
        $rs = mysql_query($sql, $this->cn);
        settype($rs, "null");
        mysql_free_result($rs);
    }

    /**
     * Ejecutamos una consulta SQl
     * @param string $query Consulta SQL
     * @return un array  de registros, cada uno siendo una array asociativo de campos
     */
    public function Execute($query) {
        if ($this->status == BD::CERRADA)
            $this->open();
        //echo $query;


        if (!$rs = mysql_query($query, $this->cn)) {
            exit($this->ErrorBD(mysql_error()));
        }

        //pasamos el recordset al array asociativo
        $registros = array();
        while ($reg = mysql_fetch_array($rs)) {
            $registros [] = $reg;
        }

        mysql_free_result($rs);
        return $registros;
    }

    /**
     * Ejecuta la consulta devolviendo una fila (registro) con todos sus campos
     * 
     * @param string $tableName Nombre de la Tabla
     * @param string $filter Filtro SQL para el WHERE
     * @return un array asociaio de campos
     *  
     */
    public function ExecuteRecord($tableName, $filter) {
        $todos = $this->Execute("SELECT * FROM $tableName WHERE $filter");
        return $todos [0];
    }

    public function ExecuteRecord2($sql) {
        $todos = $this->Execute("$sql");
        return $todos [0];
    }

    public function ExecuteRecord3($sql) {
        $todos = $this->Execute("$sql");
        return $todos [1];
    }

    public function dia_semana($num_rep_dia_semana) {
        // Para dia textual de la Semana //
        switch ($num_rep_dia_semana) {
            case 1: $dia_tex = 'Domingo';
                break;
            case 2: $dia_tex = 'Lunes';
                break;
            case 3: $dia_tex = 'Martes';
                break;
            case 4: $dia_tex = 'Miercoles';
                break;
            case 5: $dia_tex = 'Jueves';
                break;
            case 6: $dia_tex = 'Viernes';
                break;
            case 7: $dia_tex = 'Sabado';
                break;
        }
        return $dia_tex;
    }

    public function nombre_mes($numero_de_mes) {
        switch ($numero_de_mes) {
            case 1: $mes = 'Enero';
                break;
            case 2: $mes = 'Febrero';
                break;
            case 3: $mes = 'Marzo';
                break;
            case 4: $mes = 'Abril';
                break;
            case 5: $mes = 'Mayo';
                break;
            case 6: $mes = 'Junio';
                break;
            case 7: $mes = 'Julio';
                break;
            case 8: $mes = 'Agosto';
                break;
            case 9: $mes = 'Septiembre';
                break;
            case 10: $mes = 'Octubre';
                break;
            case 11: $mes = 'Noviembre';
                break;
            case 12: $mes = 'Diciembre';
                break;
        }
        return $mes;
    }

    /**
     * Ejecuta una consulta devolviendo una columna (campo) con todos sus registros
     * @param string $tableName Nombre de la Tabla
     * @param string $field Nombre del Campo a traer
     * @param string $filter Filtro del WHERE (por lo menjos debe ser 1=1)
     * @return un array asociativo de valores de cada registro
     */
    public function ExecuteField($tableName, $field, $filter) {
        $todos = $this->Execute("SELECT $field FROM $tableName WHERE $filter");
        $aux = array();
        foreach ($todos as $uno) {
            $aux [] = $uno [0];
        }
        return $aux;
    }

    /**
     * Trae todos los registros de una tabla
     * @param  string $tableName Nombre de la Tabla
     * @param $orden Campo por el cual ordenar (opcional)
     * @return un array de registros, cada uno un array asociativo
     * 
     */
    public function Executetable($tableName, $orden = "") {
        if ($orden != "")
            return $this->Execute("SELECT * FROM " . $tableName . " ORDER BY " . $orden); else
            return $this->Execute("SELECT * FROM " . $tableName);
    }

    /**
     * Trae un solo valor de la Base de datos
     * @param string $query consulta SQL (1x1)
     * @return el valor devuelto por la consulta
     */
    public function ExecuteScalar($query) {
        if ($this->status == BD::CERRADA)
            $this->open();
        $rs = mysql_query($query, $this->cn) or die($this->ErrorBD("Error en scalar " . mysql_error()));
        $reg = mysql_fetch_array($rs);
        return $reg [0];
    }

    /**
     * Devuelve la cantidad de registros de una Tabla
     * @param string $tableName Nombre de la Tabla o un array asociativo si se desea o se obtuvo de una consulta ya hecha 
     * @param string $filter Filtro de consulta WHERE
     * @return Cantidad de registros
     */
    public function RecordCount($tablename, $filter = "") {
        if (is_array($tablename)) {
            return sizeof($tablename);
        } else {
            
        }
        if ($this->status == BD::CERRADA)
            $this->open();
        if ($filter != "") {
            $rs = mysql_query("SELECT * FROM " . $tablename . " WHERE " . $filter, $this->cn);
            $total = @mysql_num_rows($rs);
            return $total;
            mysql_free_result($rs);
        } else {
            $rs = mysql_query("SELECT * FROM " . $tablename, $this->cn);
            $total = mysql_num_rows($rs);
            return $total;
            mysql_free_result($rs);
        }
    }

    /**
     * Devuelve una instruccion SQl que actualiza la tabla con los respectivos datos enviados
     * @param string $tableName Nombre de la Tabla
     * @param string $id El id a actualizar
     * @param string $carpeta La carpeta en la que se guardara los archivos de imagen, etc que se envien la ruta es relativa al documento que esta creando el onjeto bd
     * @param string $metodo El metodo que se va a usar para enviar los archivos por defecto es $_POST
     * @param string $filter Filtro de consulta WHERE
     * @return Cantidad de registros
     */
    public function ExeActualiza($tablename, $filter) {
        if ($this->status == BD::CERRADA)
            $this->open();
        $result = mysql_query("select * from $tablename where $filter", $this->cn);
        $filas = mysql_fetch_assoc($result);
        $id_actual = $filas ['id'];
        $query = '';
        foreach ($_POST as $index => $value) {
            $value = utf8_decode($value); //por precaucion
            if (!$query) {
                $query = "$index = '$value'";
            } else {
                $query .= ", $index = '$value'";
            }
        }

        if (isset($_FILES)) {
            foreach ($_FILES as $index => $file) {
                if ($file ['tmp_name'] == "") {
                    
                } else {
                    if (!$query) {
                        $nombre = rand() . "_" . $this->cleanFile(trim(ereg_replace(" ", "_", $file ['name'])));
                        $query = "$index='$nombre'";
                        $archivo = "$file[name]";
                        move_uploaded_file($file ['tmp_name'], "$this->carpeta$nombre");
                    } else {
                        $nombre = rand() . "_" . $this->cleanFile(trim(ereg_replace(" ", "_", $file ['name'])));
                        $query .= ", $index='$nombre'";
                        $archivo = "$file[name]";
                        move_uploaded_file($file ['tmp_name'], "$this->carpeta$nombre");
                    }
                }
            }

            $query = "UPDATE $tablename SET " . $query . " WHERE $filter";
            $link = mysql_query($query, $this->cn) or die("Hubo un error al intentar actualizar " . mysql_error());
            return $link;
            mysql_free_result($link);
        }
    }

    /**
     * Devuelve una instruccion SQl que inserta un nuevo dato en la tabla con los respectivos datos enviados
     * @param string $tableName Nombre de la Tabla
     * @param string $id El id a actualizar
     * @param string $carpeta La carpeta en la que se guardara los archivos de imagen, etc que se envien la ruta es relativa al documento que esta creando el onjeto bd
     * @param string $metodo El metodo que se va a usar para enviar los archivos por defecto es $_POST
     * @param string $filter Filtro de consulta WHERE
     * @return Cantidad de registros
     */
    public function ExeInserta($tablename) {
        if ($this->status == BD::CERRADA)
            $this->open();
        $query = '';
        foreach ($_POST as $index => $value) {
            $value = utf8_decode($value); //por precaucion
            if (!$query) {
                $query = "$index = '$value'";
            } else {
                $query .= ", $index = '$value'";
            }
        }

        if (isset($_FILES)) {
            foreach ($_FILES as $index => $file) {
                if ($file ['tmp_name'] == "") {
                    
                } else {
                    if (!$query) {
                        $nombre = rand() . "_" . $this->cleanFile(trim(ereg_replace(" ", "_", $file ['name'])));
                        $query = "$index='$nombre'";
                        $archivo = "$file[name]";
                        move_uploaded_file($file ['tmp_name'], "$this->carpeta$nombre");
                    } else {
                        $nombre = rand() . "_" . $this->cleanFile(trim(ereg_replace(" ", "_", $file ['name'])));
                        $query .= " ,$index='$nombre'";
                        $archivo = "$file[name]";
                        move_uploaded_file($file ['tmp_name'], "$this->carpeta$nombre");
                    }
                }
            }
            $query = "INSERT INTO $tablename SET " . $query . " ";
        }
        $link = mysql_query($query, $this->cn) or die("Error al intentar llenar los nuevos datos " . mysql_error());
        return $link;
        mysql_free_result($link);
    }

    /**
     * Metodo que elimina el registro de la bd
     *
     * @param string $tablename
     * @param string $filter
     * @return string $borrado
     */
    public function ExeElimina($tablename, $filter) {
        if ($this->status == BD::CERRADA)
            $this->open();

        $borrado = mysql_query("DELETE  FROM $tablename  WHERE  $filter", $this->cn) or die("Error el eliminar  " . mysql_error());
        return $borrado;
        mysql_free_result($borrado);
    }

    public function Exe($query) {
        if ($this->status == BD::CERRADA)
            $this->open();
        $consulta = mysql_query($query, $this->cn) or die("Hubo un problema al intentar ejecutar la consulta" . mysql_error());
        return $consulta;
        mysql_free_result($consulta);
    }

    /**
     * Metodo para eliminar el archivo
     *
     * @param String $file Nombre del archivo
     */
    public function ExeEliminaArchivo($file) {
        if (is_file($this->carpeta . "" . $file)) {
            unlink($this->carpeta . "" . $file);
        }
    }

    /**
     * Metodo para extraer la ultima modificacion de el archivo para este prop�sito solo la hora de la ultima modificacion
     * se devuelve un array asociativo para mas propiedades se se deseara
     *
     * @param String $file Nombre del archivo
     */
    public function ultima_modificacion($file) {
        if (is_file($this->carpeta . "" . $file)) {
            $propiedades = array();
            $propiedades ['fecha'] = date("d-m-Y", filemtime($this->carpeta . "" . $file));
            $propiedades ['hora'] = date("h:i:a", filemtime($this->carpeta . "" . $file));
            return $propiedades;
        }
    }

    /**
     * Ejecutamos una consulta qeu devuelve solo una fila de datos parecido al recordcpoutnpero no seleecioad todo
     *
     * @param Consulta sql $sql
     * @return array de una sola fila
     */
    public function ExecuteFila($sql) {
        if ($this->status == BD::CERRADA)
            $this->open();
        $fila = $this->Execute($sql);
        if ($fila) {
            return $fila [0];
        } else {
            return 0;
        }
    }

    public function paginacion($sql, $cuantos, $n_enlaces, $estilo_links, $funcion_ajax) {
        if ($this->status == BD::CERRADA)
            $this->open();
        $_pagi_sql = $sql;
        $_pagi_cuantos = $cuantos;
        $_pagi_nav_num_enlaces = $n_enlaces;
        $_pagi_nav_estilo = $estilo_links;
        //$_funcion_ajax = $this->funcion_ajax;
        $_funcion_ajax = $funcion_ajax;
        $_data_grid = $this->data_grid;
        $img_pagina = $this->img_navegacion;

        require '../paginator.inc.php';

        while ($reg = mysql_fetch_array($_pagi_result)) {
            $registros [] = $reg;
        }
        //mysql_free_result($registros);

        $this->menu_navegacion = $_pagi_navegacion;
        $this->info_navegacion = $_pagi_info;

        return $registros;
    }

    public function ultimo_ingreso() {
        return mysql_insert_id();
    }

    public function primeraMayuscula($txt) {
        return utf8_encode(ucwords(strtolower($txt)));
    }

    public function caracterEspecial($txt) {
        return utf8_encode($txt);
    }

    public function caracterEspecialHTML($txt) {
        return htmlentities($txt);
    }

    public function caracterTextarea($txt) {
        return nl2br($txt);
    }

    public function decimales($num) {
        return number_format($num, 2, '.', ',');
    }

    public function preparaSQL($cadena) {
        $this->open();
        if ($this->codificacion == "utf8") {
            return mysql_real_escape_string(utf8_decode($cadena));
        } else {
            return mysql_real_escape_string($cadena);
        }
    }

    public function fechaMysql($fecha) {
        $mifecha = "";
        ereg("([0-9]{1,2})/([0-9]{1,2})/([0-9]{2,4})", $fecha, $mifecha);
        $lafecha = $mifecha[3] . "-" . $mifecha[2] . "-" . $mifecha[1];
        return $lafecha;
    }

    public function fechaNormal($fecha) {
        $mifecha = "";
        ereg("([0-9]{2,4})-([0-9]{1,2})-([0-9]{1,2})", $fecha, $mifecha);
        $lafecha = $mifecha[3] . "-" . $mifecha[2] . "-" . $mifecha[1];
        return $lafecha;
    }

    public function inserta($tabla, $campos) {
        if (is_array($campos)) {
            $filas = "";
            $valores = "";
            foreach ($campos as $key => $value) {
                $filas .= " " . $key . " , ";
                if ($this->codificacion == "utf-8") {
                    $valores .= " '" . utf8_decode($this->preparaSQL($value)) . "' , ";
                } else {
                    $valores .= "'" . $this->preparaSQL($value) . "'";
                }
            }

            $filas = substr($filas, 0, strlen($filas) - 2);
            $valores = substr($valores, 0, strlen($valores) - 2);
            //echo 'insert into '.$tabla.'('.$filas.') values ('.$valores.')<br>';
            $rs = $this->Exe("insert into $tabla ($filas) values ($valores)");

            /* add */
            if ($rs) {
                return mysql_insert_id();
            }
            return false;
            /* end add */
            //echo 'insert into '.$tabla.'('.$filas.') values ('.$valores.')<br>';
        } else {
            $this->msgErrorArray();
        }
    }

    public function actualiza($tabla, $campos, $f) {
        if (is_array($campos)) {
            $cadena = "";
            foreach ($campos as $key => $value) {
                if ($this->codificacion == "utf-8") {
                    $cadena .= " " . $key . " = '" . utf8_decode($this->preparaSQL($value)) . "' , ";
                } else {
                    $cadena .= " " . $key . " = '" . $this->preparaSQL($value) . "' , ";
                }
            }

            $cadena = substr($cadena, 0, strlen($cadena) - 2);
            if ($f) {
                return $this->Exe("update $tabla set $cadena where $f");
            } else {
                $this->msgErrorId();
            }
        } else {
            $this->msgErrorArray();
        }
    }

    private function cleanFile($str) {
        return preg_replace("/[^A-Za-z0-9 _\.]/", "", $str);
    }

    public function createtable($sql) {
        if (mysql_db_query($database, $sql, $this->cn)) {
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * Insertar Registro
     * @author alan tello
     * @param string $tabla Nombre del tabla
     * @param array $campos Array campo => valor
     * @return int ID del registro insertado
     */
    public function insertar($tabla, $campos) {
        foreach ($campos as $k => $v) {
            $key.= $k . ',';
            $value.= "'$v',";
        }
        $key = substr($key, 0, strlen($key) - 1);
        $value = substr($value, 0, strlen($value) - 1);

        $query = "INSERT INTO $tabla ($key) VALUES($value)";
        $this->open();

        $rs = mysql_query($query, $this->cn);

        if ($rs) {
            return mysql_insert_id();
        }

        return mysql_error($this->cn);
    }

    public function actualizar($tabla, $campos, $filter) {
        foreach ($campos as $k => $v) {
            $cad.= $k . '="' . $v . '",';
        }
        $cad = substr($cad, 0, strlen($cad) - 1);
        $query = "UPDATE $tabla SET $cad WHERE $filter";
        
        $this->open();

        $rs = mysql_query($query, $this->cn);

        if ($rs) {
            return true;
        }
        return mysql_error($this->cn);
    }

    /**
     * Ejecutar Consulta
     * @param string $sql
     */
    public function query($sql) {
        $this->open();
        $rs = mysql_query($sql, $this->cn);
        return $rs;
    }

}

?>